﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using BBICMS.Model.ViewModel.Identity;
using System.Threading.Tasks;
using BBICMS.Model.Security;
using Newtonsoft.Json;
using BBICMS.ViewModel;
using BBICMS.Resources;
using BBICMS.Application.InputModels.Accounts;
using BBICMS.Model;
using BBICMS.Application.ViewModels.Front;
using AutoMapper;
using PagedList;
using BBICMS.Application.ViewModels;

namespace BBICMS.WebUI.Controllers
{
  
    public class AccountController : BaseController
    {

        [Authorize]
        public async Task<ActionResult> Index()
        {
            var user = await _unit.Users.GetUserByName(User.Identity.Name);
            ProfileIM vm = new ProfileIM
            {
                DisplayName = user.RealName,
                Company = user.Company,
                Phone = user.Phone
            };
            return View(vm);
        }

        [Authorize]
        [HttpPost]
        public async Task<ActionResult> UpdateProfile(ProfileIM vm)
        {
            if (!ModelState.IsValid)
            {
                var errorMes = GetModelErrorMessage();
                AR.Setfailure(errorMes);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            var user = await _unit.Users.GetUserByName(User.Identity.Name);

            user.RealName = vm.DisplayName;
            user.Company = vm.Company;
            user.Phone = vm.Phone;

            _unit.Users.Update(user);
            _unit.SaveChanges();

           
            AR.SetSuccess(string.Format(Messages.AlertCreateSuccess, EntityNames.User));
            return Json(AR, JsonRequestBehavior.DenyGet);
        }

        [Authorize]
        public ActionResult MyFavorites(int? page = 1)
        {
            CollectionListVM vm = new CollectionListVM();
            vm.PageIndex = (page ?? 1) - 1;
            vm.PageSize = 15;

            var productIds = _unit.Collections.GetAll().Where(c => c.AddedBy == User.Identity.Name).Select(c => c.ProductId).AsEnumerable();

            var query = _unit.Products.GetAll().Where(p => productIds.Contains(p.Id) && p.Active);
            var orgProducts = query.OrderByDescending(p => p.Id).Skip(vm.PageIndex * vm.PageSize).Take(vm.PageSize).ToList();

            vm.TotalCount = query.Count();

            var products = Mapper.Map<List<Product>, List<ProductVM>>(orgProducts);

            vm.ProductList = new StaticPagedList<ProductVM>(products, vm.PageIndex + 1, vm.PageSize, vm.TotalCount);        

            return View(vm);
        }

     
        [HttpPost]
        public ActionResult AddCollection(int productId)
        {
            if (User == null || !User.Identity.IsAuthenticated)
            {
                AR.Setfailure(Resources.Front.Messages.UnLogin);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            var collection = _unit.Collections.FindBy(c => c.AddedBy == User.Identity.Name && c.ProductId == productId).Count();
            if (collection > 0)
            {
                AR.SetWarning(Resources.Front.Messages.ProductIsCollectioned);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            Collection vm = new Collection
            {
                ProductId = productId,
                AddedBy = User.Identity.Name,
                AddedDate = DateTime.Now
            };

            _unit.Collections.Add(vm);
            _unit.SaveChanges();

            AR.SetSuccess(Resources.Front.Messages.AlertAddCollectionSuccess);
            return Json(AR, JsonRequestBehavior.DenyGet);
            
        }
        //删除收藏
        [HttpPost]
        public ActionResult DeleteCollection(int productId)
        {
            if (User == null || !User.Identity.IsAuthenticated)
            {
                AR.Setfailure(Resources.Front.Messages.UnLogin);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            var collection = _unit.Collections.FindBy(c => c.AddedBy == User.Identity.Name && c.ProductId == productId).FirstOrDefault();
            if (collection != null)
            {
                _unit.Collections.Delete(collection);
                _unit.SaveChanges();

                AR.SetSuccess(Resources.Front.Messages.AlertDeleteSuccess);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            AR.Setfailure(Resources.Front.Messages.AlertDeleteFailure);
            return Json(AR, JsonRequestBehavior.DenyGet);



        }


        [Authorize]
        public ActionResult UpdatePWD()
        {
            ChangePasswordIM vm = new ChangePasswordIM();           
            return View(vm);
        }

        

        [Authorize]
        [HttpPost]
        public ActionResult UpdatePWD(ChangePasswordIM vm)
        {
            if (!ModelState.IsValid)
            {
                var errorMes = GetModelErrorMessage();
                AR.Setfailure(errorMes);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
            
            var result = _unit.Users.ChangePassword(User.UserId, vm.OldPassword, vm.NewPassword);
            _unit.SaveChanges();
            if(result == 1)
            {
                AR.Setfailure(Messages.NoUser);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
            if(result == 2)
            {
                AR.Setfailure(Messages.PasswordError);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            AR.SetSuccess(string.Format(Messages.AlertUpdateSuccess, Labels.Password));
            return Json(AR, JsonRequestBehavior.DenyGet);
            
        }

        public ActionResult Login(string returnUrl)
        {
            
            LoginVM vm = new LoginVM
            {
                ReturnUrl = returnUrl
            };
            return View(vm);
        }

        //
        // POST: /Account/Login

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginVM model)
        {
            if (ModelState.IsValid)
            {
                //if (Session["SigCaptcha"] != null && Session["SigCaptcha"].ToString() != model.CaptchaText)
                //{
                //    ModelState.AddModelError("CaptchaText", "验证码不正确!");
                //    return View(model);
                //}

                var user = await _unit.Users.SignIn(model);
                //var user = db.Users.Where(u => u.Username == model.UserName && u.PasswordHash == model.Password).FirstOrDefault();
                if (user != null)
                {
                    var roles = user.Roles.Select(m => m.RoleName).ToArray();

                    user.LastActivityDate = DateTime.Now;
                    _unit.Users.Update(user);
                    _unit.SaveChanges();
                    //设置cookies
                    //   _unit.Users.SetUserCookies(model.RememberMe, user);

                  //  var roles = user.Roles.Select(m => m.RoleName).ToArray();

                    CustomPrincipalSerializeModel serializeModel = new CustomPrincipalSerializeModel();
                    serializeModel.UserId = user.Id;
                    serializeModel.RealName = user.RealName;
                    serializeModel.Avatar = user.PhotoUrl;
                    serializeModel.Roles = roles;
                    //serializeModel.Menus = GetUserMenus(user.);

                    TimeSpan timeout = FormsAuthentication.Timeout;
                    DateTime expire = DateTime.Now.Add(timeout);


                    string userData = JsonConvert.SerializeObject(serializeModel, Formatting.Indented,
                        new JsonSerializerSettings()
                        {
                            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                        });


                    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
                             1,
                             user.UserName,
                             DateTime.Now,
                             expire,
                             model.RememberMe,
                             userData);

                    string encTicket = FormsAuthentication.Encrypt(authTicket);
                    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
                    Response.Cookies.Add(faCookie);

              
                }
                else
                {
                    AR.Setfailure(Resources.Front.Messages.InvalidUserNameOrPassword);
                    return Json(AR, JsonRequestBehavior.DenyGet);
                }

              //  ModelState.AddModelError("", "");
            }else
            {
                AR.Setfailure(Resources.Front.Messages.InvalidUserNameOrPassword);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            AR.SetSuccess(Resources.Front.Messages.Wellcome);
            AR.Data = model.ReturnUrl;
            return Json(AR, JsonRequestBehavior.DenyGet);
        }


       

        //
        // POST: /Account/LogOff

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }

        //
        // GET: /Account/Register

        [AllowAnonymous]
        public ActionResult Register()
        {
            return View();
        }

        //
        // POST: /Account/Register

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Register(RegisterVM model)
        {
            if (!ModelState.IsValid)
            {
                var errorMes = GetModelErrorMessage();
                AR.Setfailure(errorMes);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }


            var result = _unit.Users.Register(model);

            if (result==1)
            {
                AR.Setfailure(Messages.CannotRegisterEmail);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            if (result == 2)
            {
                AR.Setfailure(Messages.CannotRegisterUserName);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            AR.SetSuccess(string.Format(Messages.AlertCreateSuccess, EntityNames.User));
            return Json(AR, JsonRequestBehavior.DenyGet);
        }

            
        public ActionResult AccessDenied()
        {
            return View();
        }

    
      

        #region 帮助程序
        private ActionResult RedirectToLocal(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }

        public enum ManageMessageId
        {
            ChangePasswordSuccess,
            SetPasswordSuccess,
            RemoveLoginSuccess,
        }

        //internal class ExternalLoginResult : ActionResult
        //{
        //    public ExternalLoginResult(string provider, string returnUrl)
        //    {
        //        Provider = provider;
        //        ReturnUrl = returnUrl;
        //    }

        //    public string Provider { get; private set; }
        //    public string ReturnUrl { get; private set; }

        //    public override void ExecuteResult(ControllerContext context)
        //    {
        //        OAuthWebSecurity.RequestAuthentication(Provider, ReturnUrl);
        //    }
        //}

        private static string ErrorCodeToString(MembershipCreateStatus createStatus)
        {
            // 请参见 http://go.microsoft.com/fwlink/?LinkID=177550 以查看
            // 状态代码的完整列表。
            switch (createStatus)
            {
                case MembershipCreateStatus.DuplicateUserName:
                    return "用户名已存在。请输入其他用户名。";

                case MembershipCreateStatus.DuplicateEmail:
                    return "该电子邮件地址的用户名已存在。请输入其他电子邮件地址。";

                case MembershipCreateStatus.InvalidPassword:
                    return "提供的密码无效。请输入有效的密码值。";

                case MembershipCreateStatus.InvalidEmail:
                    return "提供的电子邮件地址无效。请检查该值并重试。";

                case MembershipCreateStatus.InvalidAnswer:
                    return "提供的密码取回答案无效。请检查该值并重试。";

                case MembershipCreateStatus.InvalidQuestion:
                    return "提供的密码取回问题无效。请检查该值并重试。";

                case MembershipCreateStatus.InvalidUserName:
                    return "提供的用户名无效。请检查该值并重试。";

                case MembershipCreateStatus.ProviderError:
                    return "身份验证提供程序返回了错误。请验证您的输入并重试。如果问题仍然存在，请与系统管理员联系。";

                case MembershipCreateStatus.UserRejected:
                    return "已取消用户创建请求。请验证您的输入并重试。如果问题仍然存在，请与系统管理员联系。";

                default:
                    return "发生未知错误。请验证您的输入并重试。如果问题仍然存在，请与系统管理员联系。";
            }
        }
        #endregion

        protected override void Dispose(bool disposing)
        {
            this._unit.Dispose();
            base.Dispose(disposing);
        }
    }
}
